package cc.rengu.igas.route.core.realize.payment.impl.ncqs;

import cc.rengu.igas.channel.ncqs.biz.impl.NcqsPayServiceImpl;
import cc.rengu.igas.channel.ncqs.facade.base.Header;
import cc.rengu.igas.channel.ncqs.facade.bean.RiskInfo;
import cc.rengu.igas.channel.ncqs.facade.request.NcqsAgreePaySignAcqRequest;
import cc.rengu.igas.channel.ncqs.facade.response.NcqsAgreePaySignAcqResponse;
import cc.rengu.igas.channel.ncqs.facade.result.Result;
import cc.rengu.igas.route.common.constant.SmartRouteParamConstant;
import cc.rengu.igas.route.common.enums.SmartRouteRspEnums;
import cc.rengu.igas.route.core.realize.payment.DstChannelPaymentSignVerifyService;
import cc.rengu.igas.route.facade.bean.PayerInfo;
import cc.rengu.igas.route.facade.request.IntelligencePaymentSignVerifyRequest;
import cc.rengu.igas.route.facade.response.IntelligencePaymentSignVerifyResponse;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.oltp.service.common.dao.SignAcctInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.SignAcctInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.SignAcctInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.AcctTypeEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.BeanUtil;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.utility.dbs.Database;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * 无卡快捷协议支付签约实现
 *
 * @author xionglz
 * @version 1.0
 * @date 2020-5-25
 */
public class NcqsPaymentSignVerifyServiceImpl implements DstChannelPaymentSignVerifyService {
    private final static String TXN_NUM = "0201";
    private RgLogger rglog = RgLog.getLogger(this.getClass().getSimpleName());

    @Override
    public IntelligencePaymentSignVerifyResponse paymentSignVerify(IntelligencePaymentSignVerifyRequest intelligencePaymentSignVerifyRequest, PayerInfo payerInfo, String origSysSeqNum) throws Exception {

        NcqsAgreePaySignAcqRequest ncqsAgreePaySignAcqRequest = new NcqsAgreePaySignAcqRequest();
        IntelligencePaymentSignVerifyResponse paymentSignVerifyResponse = new IntelligencePaymentSignVerifyResponse();
        paymentSignVerifyResponse.setHeader(intelligencePaymentSignVerifyRequest.getHeader());
        //设置请求头
        Header header = new Header();
        BeanUtil.beanCopy(intelligencePaymentSignVerifyRequest.getHeader(), header);
        header.setTxnNum(TXN_NUM);
        //从业务类型转换来
        ncqsAgreePaySignAcqRequest.setBusiType("300001");
        //全额消费
        ncqsAgreePaySignAcqRequest.setBusiFuncType("111011");
        //单位结算卡
        if (AcctTypeEnum.OTHER_PUB_ACCT.getAcctType().equals(payerInfo.getAcctType())) {
            ncqsAgreePaySignAcqRequest.setCorpName(payerInfo.getAcctName());
            //单位结算卡证件id填写营业执照号
            ncqsAgreePaySignAcqRequest.setLicenceNo(payerInfo.getCertId());
        } else {
            ncqsAgreePaySignAcqRequest.setPayAcctName(payerInfo.getAcctName());
            ncqsAgreePaySignAcqRequest.setPayAcctNo(payerInfo.getAcctNo());
//            ncqsAgreePaySignWithSmsAcqRequest.setCertType(intelligencePaymentSignRequest.getPayerInfo().getCertType());
            ncqsAgreePaySignAcqRequest.setCertType("01");
            if (!StringUtil.isEmptyOrNull(payerInfo.getCertId())) {
                ncqsAgreePaySignAcqRequest.setCertNo(payerInfo.getCertId());
            }
            if (!StringUtil.isEmptyOrNull(payerInfo.getPhoneNo())) {
                ncqsAgreePaySignAcqRequest.setPhoneNo(payerInfo.getPhoneNo());
            }
            if (!StringUtil.isEmptyOrNull(payerInfo.getCardExpr())) {
                ncqsAgreePaySignAcqRequest.setExprDate(payerInfo.getCardExpr());
            }
            if (!StringUtil.isEmptyOrNull(payerInfo.getCardCvn2())) {
                ncqsAgreePaySignAcqRequest.setCvn2(payerInfo.getCardCvn2());
            }
        }
        String additionInfo = intelligencePaymentSignVerifyRequest.getAdditionInfo();
        if (StringUtil.isEmptyOrNull(additionInfo)) {
            rglog.error("无原始信息");
            throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
        } else {
            JSONObject jsonObject = JSON.parseObject(additionInfo);
            if (null == jsonObject) {
                rglog.error("无原始信息");
                throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            }
            //设置esb序列号
            String esbSequenceNumber = jsonObject.getString(ShareParamConstant.ESB_SEQUENCE_NUMBER);
            if (StringUtil.isEmptyOrNull(esbSequenceNumber)) {
                rglog.error("无通道流水信息");
                throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            }
            header.setTraceNo(esbSequenceNumber);
            //设置短信key
            String smsKey = jsonObject.getString("smsKey");
            if (StringUtil.isEmptyOrNull(smsKey)) {
                rglog.error("无短信key");
                throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            }
            ncqsAgreePaySignAcqRequest.setSmsKey(smsKey);
            //设置原通道流水号
            String origTraceNo = jsonObject.getString("settleKey");
            if (StringUtil.isEmptyOrNull(origTraceNo)) {
                rglog.error("无原始通道流水号");
                throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            }
            ncqsAgreePaySignAcqRequest.setOriTraceNo(origTraceNo);
        }
        ncqsAgreePaySignAcqRequest.setAuthMsg(intelligencePaymentSignVerifyRequest.getSmsCode());
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(intelligencePaymentSignVerifyRequest.getHeader().getInstId(), SmartRouteParamConstant.OPMS_SYS_PARAM, SmartRouteParamConstant.NCQS_INST_CODE);
        if (null == sysParam || StringUtil.isEmptyOrNull(sysParam.getParamValue())) {
            rglog.error("未获取到<{}>机构转换为银联无卡快捷数据或者机构转换数据不存在", intelligencePaymentSignVerifyRequest.getHeader().getInstId());
            throw new BizException(SmartRouteRspEnums.CONFIG_ERROR.getRespCode(), SmartRouteRspEnums.CONFIG_ERROR.getRespDesc());
        }
        ncqsAgreePaySignAcqRequest.setCupsInstCode(sysParam.getParamValue());
        RiskInfo riskInfo = new RiskInfo();
        ncqsAgreePaySignAcqRequest.setRiskInfo(riskInfo);
        ncqsAgreePaySignAcqRequest.setHeader(header);
        ncqsAgreePaySignAcqRequest.setNcqsReserve(intelligencePaymentSignVerifyRequest.getAdditionInfo());
        //调用通道签约
        DubboService dubboService = new DubboServiceImpl();
        Result<NcqsAgreePaySignAcqResponse> agreePaySign = (Result<NcqsAgreePaySignAcqResponse>)
                dubboService.callDubboInnerMethod(NcqsPayServiceImpl.class, "agreePaySign", ncqsAgreePaySignAcqRequest);
        if (!agreePaySign.isSuccess() || null == agreePaySign.getResult()) {
            rglog.error("交易未应答信息");
            throw new BizException(SmartRouteRspEnums.TRANS_TO.getRespCode(), SmartRouteRspEnums.TRANS_TO.getRespDesc());
        }
        paymentSignVerifyResponse.setRespCode(agreePaySign.getResult().getRespCode());
        paymentSignVerifyResponse.setRespDesc(agreePaySign.getResult().getRespDesc());
        paymentSignVerifyResponse.setDstChannelId("NCQS");
        if (OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equals(agreePaySign.getResult().getRespCode())) {
            paymentSignVerifyResponse.setDstChannelSsn(agreePaySign.getResult().getChannelSeqNum());
            //等级签约信息，存在则更新，失败则返回超时可继续查询或者重新发起
            regSignInfo(intelligencePaymentSignVerifyRequest.getHeader().getInstId(), payerInfo, agreePaySign.getResult().getSignNo(), origSysSeqNum);
            //至少校验三要素，借记卡校验姓名、证件类型、证件号码、手机号；信用卡校验姓名、手机号、卡有效期、CVN2；手机号必须校验
            String valBitMap = agreePaySign.getResult().getValBitMap();
            if ('1' != valBitMap.charAt(2)) {
                throw new BizException(SmartRouteRspEnums.VERIFY_NOT_ENOUGH.getRespCode(), SmartRouteRspEnums.VERIFY_NOT_ENOUGH.getRespDesc());
            }
            //存储下来
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("valBitMap", valBitMap);
            paymentSignVerifyResponse.setAdditionInfo(jsonObject.toJSONString());
        }
        return paymentSignVerifyResponse;
    }

    private void regSignInfo(String instId, PayerInfo payerInfo, String signNo, String origSysSeqNum) throws BizException {
        //处理协议号
        SignAcctInfo signAcctInfo = new SignAcctInfo();
        signAcctInfo.setAuthLimitAmt("");
        signAcctInfo.setCardHoldName(payerInfo.getAcctName());
        signAcctInfo.setCertNo(payerInfo.getCertId());
        signAcctInfo.setCertType(payerInfo.getAcctType());
        signAcctInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        signAcctInfo.setDayLimitAmt("");
        signAcctInfo.setInstId(instId);
        signAcctInfo.setNoPasswordAmt("");
        signAcctInfo.setOtherSignData("");
        signAcctInfo.setPayIndex(0);
        signAcctInfo.setRemark1("");
        signAcctInfo.setRemark1("");
        signAcctInfo.setRemark2("");
        signAcctInfo.setRemark3("");
        signAcctInfo.setRemark4("");
        signAcctInfo.setRemark5("");
        signAcctInfo.setReserveMobileNo(payerInfo.getPhoneNo());
        signAcctInfo.setSignAcctNo(payerInfo.getAcctNo());
        signAcctInfo.setSignAcctType(payerInfo.getAcctType());
        signAcctInfo.setSignBankName(payerInfo.getOpenBankNm());
        signAcctInfo.setSignBankNo(payerInfo.getOpenBankNo());
        signAcctInfo.setSignDate(DateUtil.getCurrentDate());
        signAcctInfo.setSignExpiryDate("20991231");
        //当签约类型为00时，填写银行总行机构号
        signAcctInfo.setSignInst(instId);
        signAcctInfo.setSignStatus("Y");
        signAcctInfo.setSignSysSeqNum(origSysSeqNum);
        signAcctInfo.setSignToken(payerInfo.getOpenBankNo() + "|" + signNo);
        //无卡快捷支付
        signAcctInfo.setSignTokenType("03");
        //银行级签约
        signAcctInfo.setSignType("00");
        signAcctInfo.setSingleLimitAmt("");
        signAcctInfo.setUnsignDate("");
        signAcctInfo.setUnsignSysSeqNum("");
        signAcctInfo.setUpdateTime("");
        signAcctInfo.setUserId(payerInfo.getCertId());
        signAcctInfo.setSignTokenInst(signAcctInfo.getSignInst());

        try {
            SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
            int iRetCode = signAcctInfoMapper.insertSignAcctInfo(signAcctInfo);
            if (Database.DBS_SUCCESS == iRetCode) {
                rglog.error("登记签约信息成功");
            } else if (Database.DBS_PKEY_DUPLICATE == iRetCode) {
                //更新协议号为新的协议号
                try {
                    int iRetCodeUpd = signAcctInfoMapper.updateSignAcctInfoBySignAcctNo(signAcctInfo);
                    if (Database.DBS_SUCCESS != iRetCodeUpd) {
                        //更新失败，继续使用原有协议号或者使用查询交易查询，可能存在发卡侧协议号已经更新原有协议号不能再使用的情况
                        throw new BizException(SmartRouteRspEnums.TRANS_TO.getRespCode(), SmartRouteRspEnums.TRANS_TO.getRespDesc());
                    }
                } catch (Exception e) {
                    throw new BizException(SmartRouteRspEnums.TRANS_TO.getRespCode(), SmartRouteRspEnums.TRANS_TO.getRespDesc());
                }
            } else {
                rglog.error("登记签约信息失败，需要发起签约查询");
                throw new BizException(SmartRouteRspEnums.TRANS_TO.getRespCode(), SmartRouteRspEnums.TRANS_TO.getRespDesc());
            }
        } catch (Exception e) {
            throw new BizException(SmartRouteRspEnums.TRANS_TO.getRespCode(), SmartRouteRspEnums.TRANS_TO.getRespDesc());
        }
    }
}
